#ifndef __TINYSRV_TCP_SERVER_H__
#define __TINYSRV_TCP_SERVER_H__

#include "non_copyable.h"
#include "thread.h"
#include "tcp_srv_socket.h"
#include "epoll_selector.h"
#include "client_item_base.h"
#include "spinlock.h"
#include "processing_queue.h"

#include <map>

namespace tinySrv
{

  class TCPServer
    : private TCPSrvSocket
    , private ISelectorCallback
    , private IProcessingQueueCallback
    , private ProcessingQueue
    , private EPollSelector
    , private Thread
  {
  public:
    TCPServer(std::string const &localAddress, unsigned short localPort, int backlog,
              int maxConnections, int workingThreadCount,
              std::auto_ptr<IClientFactory> clientsFactory,
              int temporaryBufferSizeForRecv = 4096);
    virtual ~TCPServer();  

  private:
    enum { SelectorWaitTimeout = 50 };
    
    bool volatile IsRun;
    int MaxConnectionCount;
    int TemporaryBufferSize;
    std::auto_ptr<IClientFactory> ClientsFactory;
    typedef RefObjPtr<ClientItemBase> ClientItemBasePtr;
    typedef std::map<ClientItemBase *, ClientItemBasePtr> ClientsPool;
    ClientsPool Clients;
    
    void ListenerFunc();
    virtual bool ProcessSocket(int sock, SelectType type, void *data);
    void OnConnect(int sock);
    void OnCloseConnection(ClientItemBase *client);
    void OnRecvData(ClientItemBase *client);  
    virtual void ProcessItem(IProcessingQueueCallback::IRefObjectPtr item);
  };

}

#endif  // !__TINYSRV_TCP_SERVER_H__
